import lib.problem as problem
import unittest

names = {
		 0: "Zero",
		 1: "One",
		 2: "Two",
		 3: "Three",
		 4: "Four",
		 5: "Five",
		 6: "Six",
		 7: "Seven",
		 8: "Eight",
		 9: "Nine",
		 10: "Ten",
		 11: "Eleven",
		 12: "Twelve",
		 13: "Thirteen",
		 14: "Fourteen",
		 15: "Fifteen",
		 16: "Sixteen",
		 17: "Seventeen",
		 18: "Eighteen",
		 19: "Nineteen",
		 20: "Twenty",
		 30: "Thirty",
		 40: "Forty",
		 50: "Fifty",
		 60: "Sixty",
		 70: "Seventy",
		 80: "Eighty",
		 90: "Ninety",
		 100: "Hundred",
		 1000: "Thousand"
		}


class Problem017(problem.Problem):
	def __init__(self):
		problem.Problem.__init__(self, 17)
		
	def getWordsForUnits(self, n):
		units = n % 10
		tens = int(n / 10) % 10
		
		unitsWord = ""
		
		if units > 0 and tens != 1:
			unitsWord = names[units]
			
		return unitsWord

	
	def getWordsForTens(self, n):
		tens = int(n / 10) % 10
		
		if tens == 0:
			return ""
		
		if tens < 2:
			# until twenty there is a full word for the numbers
			underTwenty = n % 100
			tensWord = names[underTwenty]
		else:
			tensWord = names[tens * 10]
			
		return tensWord

	
	def getWordsForHundreds(self, n):
		hundreds = int(n / 100) % 10
		
		if hundreds == 0:
			return ""
		
		hundredsWord = names[hundreds] + names[100]
		
		return hundredsWord
	
	def getWordsForThousands(self, n):
		thousands = int(n / 1000) % 10
		
		if thousands == 0:
			return ""
		
		thousandsWord = names[thousands] + names[1000]
		
		return thousandsWord
	
		
	def getWordsOfNumber(self, n):
		thousandsWord = self.getWordsForThousands(n)
		hundredsWord  = self.getWordsForHundreds(n)
		tensWord      = self.getWordsForTens(n)
		unitsWord     = self.getWordsForUnits(n)
		
		andWord = ""
		if n >= 100 and n % 100:
			andWord = "And"
		
		return thousandsWord + hundredsWord + andWord + tensWord + unitsWord
	
	def getWordsOfNumbersUntil(self, m):
		wordsList = []
		for i in range(1, m + 1):
			word = self.getWordsOfNumber(i)
			wordsList.append(word)
			
		return wordsList
	
	def getSizeOfWordsList(self, m):
		wordsList = self.getWordsOfNumbersUntil(m)
		size = 0
		for word in wordsList:			
			size += len(word)
			
		return size
	
	def solve(self):
		return self.getSizeOfWordsList(1000)
	
	
	
class Problem017Tester(unittest.TestCase):
	
	def setUp(self):
		self.p017 = Problem017()
		
	def testUnits1(self):
		self.assertEquals("One", self.p017.getWordsForUnits(1))
		
	def testUnits11(self):
		self.assertEquals("", self.p017.getWordsForUnits(11))
		
	def testUnits24(self):
		self.assertEquals("Four", self.p017.getWordsForUnits(24))
		
	def testUnits321(self):
		self.assertEquals("One", self.p017.getWordsForUnits(321))
		
	def testTens10(self):
		self.assertEquals("Ten", self.p017.getWordsForTens(10))
		
	def testTens11(self):
		self.assertEquals("Eleven", self.p017.getWordsForTens(11))
		
	def testTens30(self):
		self.assertEquals("Thirty", self.p017.getWordsForTens(30))
		
	def testTens54(self):
		self.assertEquals("Fifty", self.p017.getWordsForTens(54))
		
	def testTens254(self):
		self.assertEquals("Fifty", self.p017.getWordsForTens(54))
	
	def testHundreds100(self):
		self.assertEquals("OneHundred", self.p017.getWordsForHundreds(100))
		
	def testHundreds45(self):
		self.assertEquals("", self.p017.getWordsForHundreds(45))
		
	def testHundreds321(self):
		self.assertEquals("ThreeHundred", self.p017.getWordsForHundreds(321))
		
	def testHundreds4321(self):
		self.assertEquals("ThreeHundred", self.p017.getWordsForHundreds(4321))
		
	def testThousands1000(self):
		self.assertEquals("OneThousand", self.p017.getWordsForThousands(1000))
		
	def testThousands321(self):
		self.assertEquals("", self.p017.getWordsForThousands(321))
		
	def testThousands4321(self):
		self.assertEquals("FourThousand", self.p017.getWordsForThousands(4321))
		
	def testWordsOfNumber4321(self):
		self.assertEquals("FourThousandThreeHundredAndTwentyOne", self.p017.getWordsOfNumber(4321))
		
	def testWordsOfNumber115(self):
		self.assertEquals(20, len(self.p017.getWordsOfNumber(115)))
		
	def testWordsOfNumber342(self):
		self.assertEquals("ThreeHundredAndFortyTwo", self.p017.getWordsOfNumber(342))
		self.assertEquals(23, len(self.p017.getWordsOfNumber(342)))

	def testGetSizeOfWordsList5(self):
		self.assertEquals(19, self.p017.getSizeOfWordsList(5))
		
	def testGetSizeOfWordsList100(self):
		self.assertEquals(864, self.p017.getSizeOfWordsList(100))
		
	def testGetSizeOfWordsList1000(self):
		self.assertEquals(21124, self.p017.getSizeOfWordsList(1000))
		
	def testSolve(self):
		self.assertEquals(21124, self.p017.solve())
